package com.xuan.yupao.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuan.yupao.common.ErrorCode;
import com.xuan.yupao.enums.TeamStatusEnum;
import com.xuan.yupao.exception.BusinessException;
import com.xuan.yupao.mapper.TeamMapper;
import com.xuan.yupao.model.domain.Message;
import com.xuan.yupao.model.domain.Team;
import com.xuan.yupao.model.domain.TeamUser;
import com.xuan.yupao.model.domain.User;
import com.xuan.yupao.model.domain.dto.TeamQuery;
import com.xuan.yupao.model.domain.request.TeamJoinRequest;
import com.xuan.yupao.model.domain.request.TeamKickMemberRequest;
import com.xuan.yupao.model.domain.request.TeamUpdateRequest;
import com.xuan.yupao.model.domain.vo.TeamVo;
import com.xuan.yupao.model.domain.vo.UserVo;
import com.xuan.yupao.service.MessageService;
import com.xuan.yupao.service.TeamService;
import com.xuan.yupao.service.TeamUserService;
import com.xuan.yupao.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author 清凉茶
 * @description 针对表【team】的数据库操作Service实现
 * @createDate 2024-05-10 18:36:13
 */
@Service
@Slf4j
public class TeamServiceImpl extends ServiceImpl<TeamMapper, Team>
        implements TeamService {

    @Resource
    private TeamUserService teamUserService;

    @Resource
    private UserService userService;

    @Resource
    private MessageService messageService;

    @Resource
    private RedissonClient redissonClient;

    @Override
    @Transactional
    public boolean addTeam(Team team, User loginUser) {
        // team 参数不能为空
        if (team == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数为空");
        }

        // 队伍名称不能为空,且不能超过 20 个字符
        String teamName = team.getName();
        if (StringUtils.isBlank(teamName) || teamName.length() > 20) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "队伍名称不能为空且不能过长");
        }
        // 队伍描述不能为空,且不能超过 512 个字符
        String description = team.getDescription();
        if (description.length() > 512) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "队伍描述不能为空且不能过长");
        }
        // 队伍的人数必须大于0,且上限为 10
        Integer maxNum = team.getMaxNum();
        if (maxNum < 1 || maxNum > 10) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "队伍人数不符合要求");
        }
        // 超时时间为空,则表示不设置过期时间;若设置了超时时间,则该时间必须大于当前时间
        Date expireTime = team.getExpireTime();
        if (expireTime != null && expireTime.before(new Date())) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "队伍过期时间设置非法");
        }

        // 队伍状态: 公开,私有,加密(必须有密码,且应符合要求), 该参数为 null 默认为公开 -0
        Integer status = Optional.ofNullable(team.getStatus()).orElse(0);
        TeamStatusEnum statusEnum = TeamStatusEnum.getEnumValue(status);
        if (statusEnum == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "队伍状态不符合要求");
        }
        // 若队伍状态为加密则需要密码则长度需小于32
        if (TeamStatusEnum.SECRET.equals(statusEnum)) {
            String password = team.getPassword();
            if (password == null || password.length() > 32) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "队伍密码过长");
            }
        }


        // 对加入队伍个数判断及数据库存储加分布式锁
        String lockKey = String.format("yupao:addTeam:%d", loginUser.getId());
        RLock lock = redissonClient.getLock(lockKey);
        try {
            if (lock.tryLock(0, -1, TimeUnit.MILLISECONDS)) {
                log.info("getLock:" + Thread.currentThread());

                // 每个用户最多是 5 个队伍的队长
                // 注意: 已经过期的队伍不能计入其中
                Long userId = loginUser.getId();
                QueryWrapper<Team> teamQueryWrapper = new QueryWrapper<>();
                teamQueryWrapper.eq("user_id", userId);
                teamQueryWrapper.and(wrapper -> wrapper.isNull("expire_time").or().gt("expire_time", new Date()));
                long count = this.count(teamQueryWrapper);
                if (count >= 5) {
                    throw new BusinessException(ErrorCode.PARAMS_ERROR, "每个用户最多创建 5 个队伍");
                }

                // 往 team 表 和 team_user 插入记录
                team.setCreateUserId(userId);
                team.setUserId(userId);
                boolean save = this.save(team);
                if (!save) {
                    throw new BusinessException(ErrorCode.SYSTEM_ERROR, "新增队伍失败");
                }
                TeamUser teamUser = new TeamUser();
                teamUser.setTeamId(team.getId());
                teamUser.setUserId(userId);
                return teamUserService.save(teamUser);
            }
        } catch (InterruptedException e) {
            log.error("addTeam error", e);
            return false;
        } finally {
            if (lock.isHeldByCurrentThread()) {
                try {
                    Thread.sleep(1500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                log.info("unLock:" + Thread.currentThread());
                lock.unlock();
            }
        }

        throw new BusinessException(ErrorCode.TOO_MANY_REQUEST, "创建队伍操作过于频繁");
    }

    @Override
    public boolean updateTeam(TeamUpdateRequest teamUpdateRequest, User loginUser) {
        // 校验 teamUpdateRequest 是否为空和用户是否登录
        if (teamUpdateRequest == null || teamUpdateRequest.getId() < 1) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数为空");
        }
        // 用户必须登录
        if (loginUser == null || loginUser.getId() < 1) {
            throw new BusinessException(ErrorCode.NOT_LOGIN);
        }

        // 队伍名称不为空时不能超过 20 个字符
        String teamName = teamUpdateRequest.getName();
        if (teamName != null && teamName.length() > 20) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "队伍名称过长");
        }
        // 队伍描述不为空时不能超过 512 个字符
        String description = teamUpdateRequest.getDescription();
        if (description != null && description.length() > 512) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "队伍描述过长");
        }
        // 超时时间为空,则表示不设置过期时间;若设置了超时时间,则该时间必须大于当前时间
        Date expireTime = teamUpdateRequest.getExpireTime();
        if (expireTime != null && expireTime.before(new Date())) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "队伍过期时间设置非法");
        }
        // 更新后的队伍的人数必须大于0,且上限为 10
        Integer maxNum = teamUpdateRequest.getMaxNum();
        if (maxNum == null || (maxNum < 1 || maxNum > 10)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "队伍人数不符合要求");
        }

        Long teamId = teamUpdateRequest.getId();
        if (teamId == null || teamId < 1) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数非法");
        }
        Team oldTeam = this.getById(teamId);
        if (oldTeam == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "队伍不存在");
        }
        QueryWrapper<TeamUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("team_id", teamId);
        long teamCurrentNum = teamUserService.count(queryWrapper);
        if (maxNum < teamCurrentNum) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "更新队伍人数小于当前队伍人数");
        }

        // 只有管理员或队长才能修改队伍信息
        if (!(userService.isAdmin(loginUser) || loginUser.getId().equals(oldTeam.getUserId()))) {
            throw new BusinessException(ErrorCode.NOT_AUTH);
        }

        // 若要修改队伍状态为加密状态,则必须设置密码
        String password = teamUpdateRequest.getPassword();
        TeamStatusEnum oldStatusEnum = TeamStatusEnum.getEnumValue(oldTeam.getStatus());
        TeamStatusEnum currentStatusEnum = TeamStatusEnum.getEnumValue(teamUpdateRequest.getStatus());

        boolean isSecret = TeamStatusEnum.SECRET.equals(oldStatusEnum) || TeamStatusEnum.SECRET.equals(currentStatusEnum);
        if (isSecret && StringUtils.isBlank(password)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "加密队伍必须设置密码");
        }
        if (isSecret && (StringUtils.isBlank(password) || password.length() > 32)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "队伍密码不符合要求");
        }

        Team team = new Team();
        BeanUtils.copyProperties(teamUpdateRequest, team);
        return this.updateById(team);
    }


    @Override
    public List<Team> listTeams(TeamQuery teamQuery, boolean isAdmin) {
        // 组合查询条件
        QueryWrapper<Team> queryWrapper = combineQueryConditions(teamQuery, isAdmin, false);
        Page<Team> page = new Page<>(teamQuery.getPageNum(), teamQuery.getPageSize());
        Page<Team> teamPage = this.page(page, queryWrapper);
        if (teamPage.getRecords() == null || teamPage.getRecords().isEmpty()) {
            return new ArrayList<>();
        }
        return teamPage.getRecords();
    }

    @Override
    public List<Team> listPage(TeamQuery teamQuery, boolean isAdmin) {
        // 组合查询条件
        QueryWrapper<Team> queryWrapper = combineQueryConditions(teamQuery, isAdmin, false);
        // 分页查询队伍信息
        Page<Team> page = new Page<>(teamQuery.getPageNum(), teamQuery.getPageSize());
        Page<Team> teamPage = this.page(page, queryWrapper);
        return teamPage.getRecords();
    }

    @Override
    public List<Team> listTeamsCreateOrJoin(TeamQuery teamQuery, boolean isAdmin) {
        // 组合查询条件
        QueryWrapper<Team> queryWrapper = combineQueryConditions(teamQuery, isAdmin, true);
        // 加上分页信息
        Page<Team> page = new Page<>(teamQuery.getPageNum(), teamQuery.getPageSize());
        Page<Team> teamPage = this.page(page, queryWrapper);

        List<Team> teamList = this.page(teamPage, queryWrapper).getRecords();
        if (teamList == null || teamList.isEmpty()) {
            return new ArrayList<>();
        }
        return teamList;
    }

    @Override
    public List<TeamVo> getTeamInfoById(Long teamId, User loginUser) {
        Team team = this.getById(teamId);
        if (team == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "队伍不存在");
        }

        //
        return this.addExtraTeamInfo(Collections.singletonList(team), loginUser);
    }

    @Override
    public List<UserVo> getTeamMemberInfo(Long teamId, long loginUserId) {
        QueryWrapper<TeamUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("team_id", teamId);
        List<Long> userIdList = teamUserService.list(queryWrapper).stream().map(TeamUser::getUserId).collect(Collectors.toList());

        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.ne("id", loginUserId);
        userQueryWrapper.in("id", userIdList);
        List<User> userList = userService.list(userQueryWrapper);
        // 对用户信息进行脱敏
        return userList.stream().map(user -> userService.getSafetyUser(user)).collect(Collectors.toList());
    }

    @Override
    public boolean kickMember(TeamKickMemberRequest kickMemberRequest, User loginUser) {
        Long teamId = kickMemberRequest.getTeamId();
        Long userId = kickMemberRequest.getUserId();
        log.info("[kickMember] teamId=" + teamId + ", userId=" + userId);
        if (teamId == null || userId == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数为空");
        }
        if (teamId < 1 || userId < 1) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数非法");
        }

        // 1. 判断队伍是否存在及登录用户是否为队长
        QueryWrapper<Team> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", teamId);
        queryWrapper.and(wrapper -> wrapper.isNull("expire_time").or().gt("expire_time", new Date()));
        Team team = this.getOne(queryWrapper);
        if (team == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "队伍不存在");
        }
        if (!team.getUserId().equals(loginUser.getId())) {
            throw new BusinessException(ErrorCode.NOT_AUTH, "无权限");
        }

        if (team.getUserId().equals(userId)) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "不能将自己踢出队伍");
        }

        // 2. 判断要踢出的成员是否在该队伍中
        QueryWrapper<TeamUser> teamUserQueryWrapper = new QueryWrapper<>();
        teamUserQueryWrapper.eq("team_id", teamId).eq("user_id", userId);
        long count = teamUserService.count(teamUserQueryWrapper);
        if (count < 1) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "该用户不在队伍中");
        }

        // 删除 队伍-用户 关系表记录
        boolean result = teamUserService.remove(teamUserQueryWrapper);
        if (!result) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "移除队员失败");
        }
        return true;
    }


    @Override
    @Transactional
    public boolean deleteTeam(long teamId, User loginUser) {
        if (teamId < 1) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "队伍id非法");
        }
        if (loginUser == null || loginUser.getId() < 1) {
            throw new BusinessException(ErrorCode.NOT_LOGIN);
        }
        Team team = this.getById(teamId);
        if (team == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "队伍不存在");
        }
        if (!team.getUserId().equals(loginUser.getId())) {
            throw new BusinessException(ErrorCode.NOT_AUTH, "无权限");
        }

        // 删除队伍
        boolean result = this.removeById(teamId);
        if (!result) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "删除队伍失败");
        }
        // 删除 team-user 关系表记录的所有记录
        QueryWrapper<TeamUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("team_id", teamId);
        result = teamUserService.remove(queryWrapper);
        if (!result) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "删除队伍关系记录失败");
        }
        // 删除队伍的聊天记录
        QueryWrapper<Message> messageQueryWrapper = new QueryWrapper<>();
        messageQueryWrapper.eq("team_id", teamId);
        return messageService.remove(messageQueryWrapper);
    }


    @Override
    @Transactional
    public boolean quitTeam(Long teamId, Long userId) {
        if (teamId == null || teamId < 1) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        QueryWrapper<TeamUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("team_id", teamId);
        queryWrapper.eq("user_id", userId);
        long count = teamUserService.count(queryWrapper);
        if (count < 1) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "未加入队伍");
        }
        //
        queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("team_id", teamId);
        long joinNum = teamUserService.count(queryWrapper);
        if (joinNum == 1) {
            // 队伍人数为 1, 解散队伍
            this.removeById(teamId);
        } else {
            // 当前用户若为队长且房间剩余人数>1,将队长职位顺位给当前房间中第二时间加入的成员
            Team team = this.getById(teamId);
            if (team.getUserId().equals(userId)) {
                // 上面该 queryWrapper 有且仅设置了 eq("team_id", teamId)
                queryWrapper.last("order by id asc limit 2");
                List<TeamUser> teamUserList = teamUserService.list(queryWrapper);
                if (teamUserList.isEmpty() || teamUserList.size() < 2) {
                    throw new BusinessException(ErrorCode.PARAMS_ERROR);
                }
                Long newUserId = teamUserList.get(1).getUserId();
                Team updateTeam = new Team();
                updateTeam.setId(teamId);
                updateTeam.setUserId(newUserId);
                boolean result = this.updateById(updateTeam);
                if (!result) {
                    throw new BusinessException(ErrorCode.SYSTEM_ERROR, "更新队伍队长失败");
                }
            }
        }
        // 移除 team-user 关系
        queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("team_id", teamId);
        queryWrapper.eq("user_id", userId);
        return teamUserService.remove(queryWrapper);
    }

    @Override
    public Boolean joinTeam(TeamJoinRequest teamJoinRequest, User loginUser) {
        Long teamId = teamJoinRequest.getTeamId();
        if (teamId < 1) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        // 1. 只能加入状态为公开或加密的房间,并且未达到过期时间的房间 (查询 team 表)
        // 若加入状态为加密的房间,需要对密码进行验证 (查询 team 表)
        Team team = this.getById(teamId);
        if (team == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "队伍不存在");
        }
        TeamStatusEnum statusEnum = TeamStatusEnum.getEnumValue(team.getStatus());
        if (TeamStatusEnum.PRIVATE.equals(statusEnum)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "禁止加入私有队伍");
        }
        if (TeamStatusEnum.SECRET.equals(statusEnum)) {
            String password = teamJoinRequest.getPassword();
            String teamPassword = team.getPassword();
            if (StringUtils.isBlank(password) || !password.equals(teamPassword)) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "密码错误");
            }
        }

        // 2. 用户加入队伍上限为10个 (查询 team-user 关系表, 条件:userId)
        //    未到达过期时间的队伍 或 过期时间为null
        Long userId = loginUser.getId();
        String lockKey = String.format("yupao:joinTeam:%d:%d", teamId, userId);
        RLock lock = redissonClient.getLock(lockKey);
        try {
            if (lock.tryLock(0, -1, TimeUnit.MILLISECONDS)) {
                QueryWrapper<TeamUser> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("user_id", userId);
                // 1) 查出与该用户关联的队伍 id
                List<Long> teamIdList = teamUserService.list(queryWrapper).stream().map(TeamUser::getTeamId).collect(Collectors.toList());
                // 2) 查询未达到过期时间的队伍数量
                QueryWrapper<Team> teamQueryWrapper = new QueryWrapper<>();
                if (!CollectionUtils.isEmpty(teamIdList)) {
                    teamQueryWrapper.in("id", teamIdList);
                    teamQueryWrapper.and(wrapper -> wrapper.isNull("expire_time").or().gt("expire_time", new Date()));
                    long userJoinTeamNum = this.count(teamQueryWrapper);
                    if (userJoinTeamNum >= 10) {
                        throw new BusinessException(ErrorCode.PARAMS_ERROR, "一个用户最多加入 10 个队伍");
                    }
                }
                // 3. 不能加入剩余人数小于 1的房间(count聚合查询),只能加入人数未满的队伍  (查询 team-user 关系表, 条件:teamId)
                queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("team_id", teamId);

                long teamHasNum = teamUserService.count(queryWrapper);
                if (teamHasNum < 1 || teamHasNum >= team.getMaxNum()) {
                    throw new BusinessException(ErrorCode.PARAMS_ERROR, "队伍不存在或队伍人数已满");
                }
                // 4. 不能重复加入同一个队伍  (查询 team-user 关系表, 两个条件:teamId, userId)
                queryWrapper.eq("user_id", userId);
                long isJoin = teamUserService.count(queryWrapper);
                if (isJoin > 0) {
                    throw new BusinessException(ErrorCode.PARAMS_ERROR, "不能重复加入队伍");
                }
                TeamUser teamUser = new TeamUser();
                teamUser.setTeamId(teamId);
                teamUser.setUserId(userId);
                return teamUserService.save(teamUser);
            }
        } catch (InterruptedException e) {
            log.error("joinTeam error", e);
        } finally {
            if (lock.isHeldByCurrentThread()) {
                try {
                    Thread.sleep(1500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                log.info("unLock:" + Thread.currentThread());
                lock.unlock();
            }
        }
        throw new BusinessException(ErrorCode.TOO_MANY_REQUEST, "加入队伍操作过于频繁");
    }


    /**
     * 根据查询条件查询符合要求的队伍
     *
     * @param teamQuery     查询条件
     * @param isAdmin       当前用户是否为管理员(可以未登录)
     * @param isNeedPrivate 该参数只在用户查看已加入队伍或创建队伍页面使用(true),其他页面为false
     * @return 符合要求的队伍
     */
    private QueryWrapper<Team> combineQueryConditions(TeamQuery teamQuery, boolean isAdmin, boolean isNeedPrivate) {
        QueryWrapper<Team> queryWrapper = new QueryWrapper<>();
        // 组合查询条件
        if (teamQuery != null) {
            // 根据队伍 id 查询
            Long teamId = teamQuery.getId();
            if (teamId != null) {
                queryWrapper.eq("id", teamId);
            }
            List<Long> idList = teamQuery.getIdList();
            if (!CollectionUtils.isEmpty(idList)) {
                queryWrapper.in("id", idList);
            }
            // 根据队伍名称查询
            String teamName = teamQuery.getName();
            if (StringUtils.isNotBlank(teamName)) {
                queryWrapper.like("name", teamName);
            }
            // 根据队伍描述查询
            String description = teamQuery.getDescription();
            if (StringUtils.isNotBlank(description)) {
                queryWrapper.like("description", description);
            }
            // 根据搜索信息从 队伍名称和队伍描述 or 查询
            String searchText = teamQuery.getSearchText();
            if (StringUtils.isNotBlank(searchText)) {
                queryWrapper.and(qw -> qw.like("name", searchText).or().like("description", searchText));
            }
            // 根据 队长id 查询
            Long userId = teamQuery.getUserId();
            if (userId != null && userId > 0) {
                queryWrapper.eq("user_id", userId);
            }
            // 根据队伍的最大人数查询
            Integer maxNum = teamQuery.getMaxNum();
            if (maxNum != null && maxNum > 0) {
                queryWrapper.eq("max_num", maxNum);
            }
            // 根据队伍状态查询
            TeamStatusEnum statusEnum = TeamStatusEnum.getEnumValue(teamQuery.getStatus());
            if (statusEnum == null) {
                statusEnum = TeamStatusEnum.PUBLIC;
            }
            // 私密状态的房间只有管理员可以查看
            if (statusEnum.equals(TeamStatusEnum.PRIVATE) && !isAdmin) {
                throw new BusinessException(ErrorCode.NOT_AUTH);
            }
            // 用户已加入队伍和创建队伍页面需要展示所有状态的队伍
            if (isNeedPrivate) {
                queryWrapper.in("status", Arrays.asList(1, 2, 0));
            } else {
                // 公开队伍页面和加密队伍列表页只需要展示对应状态的队伍即可
                queryWrapper.eq("status", statusEnum.getValue());
            }
        }
        // 不展示已过期的队伍
        // expireTime == null or expireTime > now()
        queryWrapper.and(qw -> qw.isNull("expire_time").or().gt("expire_time", new Date()));
        return queryWrapper;
    }


    @Override
    public List<TeamVo> addExtraTeamInfo(List<Team> teamList, User loginUser) {
        List<TeamVo> teamVoList = new ArrayList<>();
        for (Team team : teamList) {
            TeamVo teamVo = new TeamVo();
            BeanUtils.copyProperties(team, teamVo);

            // teamUserVo.setLeaderName(new UserVo());  查询队长信息
            User user = userService.getById(team.getUserId());
            if (user != null && user.getId() > 0) {
                teamVo.setLeaderName(user.getUsername());
            }
            // teamUserVo.setHasJoinNum(0L);    返回已加入队伍的人数(查询 team-user 关系表)
            QueryWrapper<TeamUser> teamUserQueryWrapper = new QueryWrapper<>();
            teamUserQueryWrapper.eq("team_id", team.getId());
            long hasJoinNum = teamUserService.count(teamUserQueryWrapper);
            teamVo.setHasJoinNum(hasJoinNum);
            // teamUserVo.setHasJoin(false);    返回当前用户是否加入该队伍(查询 team-user 关系表)
            // 当前登录已登录才返回该信息
            if (loginUser != null && loginUser.getId() > 0) {
                teamUserQueryWrapper.eq("user_id", loginUser.getId());
                long hasJoin = teamUserService.count(teamUserQueryWrapper);
                if (hasJoin > 0) {
                    teamVo.setHasJoin(true);
                }
            }
            teamVoList.add(teamVo);
        }
        return teamVoList;
    }


}




